package machine;

import java.awt.Toolkit;

import support.State;
import support.WashingCycle;

import components.Drum;
import components.Engine;
import components.Heater;
import components.Panel;
import components.Programator;
import components.WatterProvider;

import exceptions.NotInValidStateException;

public abstract class WashingMachine {
	private Engine engine;
	private Heater heater;
	private Panel panel;
	private Programator programator;
	private Drum drum;
	private WatterProvider watterProvider;
	private boolean isRunning;
	private State state;

	/**
	 * @param engine
	 * @param heater
	 * @param panel
	 * @param programator
	 * @param drum
	 */
	public WashingMachine(Engine engine, Heater heater, Panel panel,
			Programator programator, Drum drum, WatterProvider watterProvider) {
		this.engine = engine;
		this.heater = heater;
		this.panel = panel;
		this.programator = programator;
		this.drum = drum;
		this.watterProvider = watterProvider;
	}

	public void turnOn() {
		if (state != State.ON) {
			state = State.ON;
			isRunning = false;
			System.out.println("Washing machine is turned on.");
		} else {
			throw new NotInValidStateException(
					"Washing machine is already turned on.");
		}
	}

	public void turnOff() {
		if (state != State.OFF && !isRunning) {
			state = State.OFF;
			engine.stopEngine();
			programator.setProgramSelected(false);
			System.out.println("Washing machine is turned on.");

		} else {
			throw new NotInValidStateException(
					"Washing machine is already turned off.");
		}
	}

	public void startWashingMachine(WashingCycle washingCycle) {
		washingCycle.startCycle();
	}

	public void startWashing() {
		if (programator.isProgramSelected() && drum.areDoorsClosed()
				&& !isRunning) {

			isRunning = true;
			watterProvider.addWatter((drum.getLoad() * 3) / 4 );
			heater.increaseTemp(programator.getTemperature());
			engine.startEngine();
			engine.increaseSpeed(programator.getRounds());

		} else {
			Toolkit.getDefaultToolkit().beep();
			throw new NotInValidStateException(
					"Washing machine is not ready !!!");
		}
	}

	public void stopWashing() {
		engine.stopEngine();
		watterProvider.emptyWatterProvider();
		isRunning = false;
	}

	public void startRinsing() {
		isRunning = true;
		watterProvider.addWatter((drum.getLoad() * 3) / 4);
		engine.startEngine();
		engine.increaseSpeed(programator.getRounds() / 2);

	}

	public void stopRinsing() {
		isRunning = false;
		engine.stopEngine();
		watterProvider.emptyWatterProvider();
	}

	public void startSpinning() {
		engine.startEngine();
		engine.increaseSpeed(programator.getRounds());
	}

	public Programator getProgramator() {
		return programator;
	}

	public void setProgramator(Programator programator) {
		this.programator = programator;
	}

	public Engine getEngine() {
		return engine;
	}

	public Drum getDrum() {
		return drum;
	}

	public WatterProvider getWatterProvider() {
		return watterProvider;
	}

}
